package com.spring.theory.bean.aware;

import javax.annotation.PostConstruct;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Slf4j
@Configuration
public class AwareConfig implements InitializingBean, ApplicationContextAware {

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        log.info("AwareConfig的ApplicationContextAware的执行");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        log.info("AwareConfig的InitializingBean执行初始化");
    }

    @Autowired
    public void setApplicationContextWithAutowired(ApplicationContext applicationContext) {
        log.info("AwareConfig 使用 @Autowired 注解，依赖注入容器是:" + applicationContext);
    }

    @PostConstruct
    public void init() {
        log.info("AwareConfig使用 @PostConstruct 注解初始化");
    }

    /**
     * 配置类里重写了bean工厂后处理器，会导致 @AutoWired、@PostConstruct等注解失效（错过了bean后处理器加载的时机）
     * --因为配置类是由bean工厂后处理器加载；配置类不加载，里面需要bean后处理器识别的注解会错过加载的时机
     * 加上修饰符static 让bean工厂后处理器，伴随类加载注入。可以解决这些注解失效的问题
     */
    @Bean
    public BeanFactoryPostProcessor processor2() {
        return new BeanFactoryPostProcessor() {
            @Override
            public void postProcessBeanFactory(ConfigurableListableBeanFactory processor) throws BeansException {
                log.info("AwareConfig的 BeanFactoryPostProcessor 执行 processor2");
            }
        };
    }
}
